﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Caching;
using System.Web.Mvc;
using AutoMapper;
using Mehdime.Entity;
using WikeSoft.Core;
using WikeSoft.Core.Exception;
using WikeSoft.Core.Extension;
using WikeSoft.Data;
using WikeSoft.Data.Models;
using WikeSoft.Enterprise.Entities;
using WikeSoft.Enterprise.Interfaces.Sys;
using WikeSoft.Enterprise.Models.Filters.Sys;
using WikeSoft.Enterprise.Models.Sys;

namespace WikeSoft.Enterprise.AppServices.Sys
{
    /// <summary>
    /// 数据字典服务
    /// </summary>
    public class DataDictionaryService : IDataDictionaryService
    {
        private readonly IMapper _mapper;
        private readonly IDbContextScopeFactory _dbContextScopeFactory;
        private ObjectCache _cache;
        private const string Config = "wikesoft.datadictionary";
        public DataDictionaryService(IMapper mapper, IDbContextScopeFactory dbContextScopeFactory)
        {
            _mapper = mapper;
            _dbContextScopeFactory = dbContextScopeFactory;
            _cache = MemoryCache.Default;
        }

        /// <summary>
        ///  添加
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool Add(DataDictionayAddModel model)
        {
            using (var scope = _dbContextScopeFactory.Create())
            {
                var db = scope.DbContexts.Get<WikeDbContext>();
                var entity = _mapper.Map<DataDictionayAddModel, SysDataDictionay>(model);

                int count = db.SysDataDictionays.Count(c => c.GroupCode == model.GroupCode && c.DictionayCode == model.DictionayCode && c.IsDelete == false);
                if (count > 0)
                {
                    throw new TipInfoException(string.Format("字典编号“{0}”已存在", model.DictionayCode));
                }
                var group = db.SysDataDictionays.FirstOrDefault(c => c.GroupCode == model.GroupCode && c.IsDelete==false);
                if (group != null)
                {
                    if (!group.GroupName.Equals(model.GroupName))
                    {
                        entity.GroupName = group.GroupName;
                    }
                }
                db.SysDataDictionays.Add(entity);
                _cache.Remove(Config);
                return scope.SaveChanges() > 0;
            }
        }

        /// <summary>
        ///  编辑
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool Edit(DataDictionayEditModel model)
        {
            using (var scope = _dbContextScopeFactory.Create())
            {
                var db = scope.DbContexts.Get<WikeDbContext>();
                var entity = db.SysDataDictionays.Load(model.Id);

                int count = db.SysDataDictionays.Count(c => c.GroupCode == model.GroupCode && c.DictionayCode == model.DictionayCode && c.Id!=model.Id && c.IsDelete == false);
                if (count > 0)
                {
                    throw new TipInfoException(string.Format("字典编号“{0}”已存在",model.DictionayCode));
                }

                var group = db.SysDataDictionays.FirstOrDefault(c => c.GroupCode == model.GroupCode && c.Id!=model.Id && c.IsDelete == false);
                if (group != null)
                {
                    if (!group.GroupName.Equals(model.GroupName))
                    {
                        model.GroupName = group.GroupName;
                    }
                }

                _mapper.Map(model, entity);
                scope.SaveChanges();
                _cache.Remove(Config);
                return true;
            }
        }

        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public DataDictionayEditModel Find(string id)
        {
            using (var scope = _dbContextScopeFactory.CreateReadOnly())
            {
                var db = scope.DbContexts.Get<WikeDbContext>();
                var entity = db.SysDataDictionays.Load(id);
                var model = _mapper.Map<SysDataDictionay, DataDictionayEditModel>(entity);
                return model;
            }
        }

        /// <summary>
        /// 验证字典名是否重复
        /// </summary>
        /// <param name="dictionaryId">字典id，可以为空，为空表示添加</param>
        /// <param name="dictionaryName">字典名称</param>
        /// <returns></returns>
        public bool IsExists(string dictionaryId, string dictionaryName)
        {
            using (var scope = _dbContextScopeFactory.CreateReadOnly())
            {
                var db = scope.DbContexts.Get<WikeDbContext>();
                var query = db.SysDataDictionays.Where(x => x.DictionayName == dictionaryName && x.IsDelete == false);
                if (dictionaryId.IsNotBlank())
                {
                    query = query.Where(x => x.Id != dictionaryId);
                }
                return query.Any();
            }
        }

        /// <summary>
        /// 根据分组编码获取数据字典
        /// </summary>
        /// <param name="groupCode"></param>
        /// <returns></returns>
        public IList<SelectListItem> GetByGroupCode(string groupCode)
        {
            var datas = GetAll();
            return datas.Where(x => x.Useable == true && x.GroupCode == groupCode).OrderBy(x=>x.SortIndex).Select(x => new SelectListItem
            {
                Value = x.Id.ToString(),
                Text = x.DictionayName
            }).ToList();
        }

        public IList<DataDictionayModel> GetListByGroupCode(string groupCode)
        {
            var datas = GetAll();
            return datas.Where(x => x.Useable == true && x.GroupCode == groupCode).ToList();
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="filters"></param>
        /// <returns></returns>
        public PagedResult<DataDictionayModel> Query(DataDictionaryFilter filters)
        {
            using (var scope = _dbContextScopeFactory.CreateReadOnly())
            {
                var db = scope.DbContexts.Get<WikeDbContext>();
                var query = db.SysDataDictionays.Where(x =>x.IsDelete ==false);
                if (filters.DictionayName.IsNotBlank())
                {
                    query = query.Where(x => x.DictionayName.Contains(filters.DictionayName));
                }
                if (filters.keywords.IsNotBlank())
                {
                    query = query.Where(x => x.DictionayName.Contains(filters.keywords) ||
                                             x.GroupName.Contains(filters.keywords));
                }
                if (filters.GroupCode.IsNotBlank())
                {
                    query = query.Where(c => c.GroupCode == filters.GroupCode);
                }
                return query.OrderByCustom(filters.sidx, filters.sord)
                    .Select(item => new DataDictionayModel
                    {
                        Id = item.Id,
                        DictionayName = item.DictionayName,
                        DictionayCode = item.DictionayCode,
                        GroupName = item.GroupName,
                        GroupCode = item.GroupCode,
                        Useable = item.Useable,
                        SortIndex = item.SortIndex
                    }).Paging(filters.page, filters.rows);
            }
        }

        public bool Delete(IList<string> ids)
        {
            using (var scope = _dbContextScopeFactory.Create())
            {
                var db = scope.DbContexts.Get<WikeDbContext>();
                var users = db.SysDataDictionays.Where(x => ids.Contains(x.Id)).ToList();

                users.ForEach(c =>
                {
                    c.IsDelete = true;
                });
                _cache.Remove(Config);
                return scope.SaveChanges() > 0;
            }
        }

        private List<DataDictionayModel> GetAll()
        {
            List<DataDictionayModel> cache = _cache.Get(Config) as List<DataDictionayModel>;

            if (cache != null)
            {
                return cache;
            }

            using (var scope = _dbContextScopeFactory.CreateReadOnly())
            {
                var db = scope.DbContexts.Get<WikeDbContext>();
                var query = db.SysDataDictionays.Where(x => true);


                var data = query.Select(item => new DataDictionayModel
                    {
                        Id = item.Id,
                        DictionayName = item.DictionayName,
                        DictionayCode = item.DictionayCode,
                        GroupName = item.GroupName,
                        GroupCode = item.GroupCode,
                        Useable = item.Useable,
                        SortIndex = item.SortIndex

                    }).ToList();

                cache = data;
                _cache.Add(Config, cache, ObjectCache.InfiniteAbsoluteExpiration);

                return data;
            }
        }
    }
}
